package com.zyx.spider.site.qianzhan;

import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.zyx.spider.common.RobotsTxtParser;
import lombok.extern.slf4j.Slf4j;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.HexFormat;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

@Slf4j
@Component
@ConditionalOnProperty(
        name = "spider.site.qianzhan.enabled", // 要检查的属性名
        havingValue = "true",        // 只有当 spider.site.qianzhan.enabled 的值为 "true" 时才加载
        matchIfMissing = false       // 如果 spider.site.qianzhan.enabled 不存在，则不加载 (默认行为)
)
public class QZNewsCrawlerTask {


    private final RobotsTxtParser parser = new RobotsTxtParser("https://t.qianzhan.com/");

    // 示例新闻网站URL
    private static final String NEWS_URL = "https://t.qianzhan.com/caijing/";
    // 模拟浏览器UA
    private static final String USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36";

    // 初始化缓存：以url hash值为键，缓存分页URL
    private final Cache<String, String> pagerCache = Caffeine.newBuilder()
            .expireAfterWrite(10, TimeUnit.MINUTES) // 设置缓存过期时间
            .maximumSize(100) // 设置最大缓存条目数
            .build();

    public QZNewsCrawlerTask() throws IOException {
    }

    @Async
    @Scheduled(fixedRate = 30, initialDelay = 5, timeUnit = TimeUnit.SECONDS)
    public void extraNewsColumnList() {
        log.info("开始执行【前瞻网】新闻抓取任务...");

        try {
            String url = NEWS_URL;
            String key = "";
            // 获取缓存大小
            long size = pagerCache.estimatedSize();
            if (size == 0) {
                log.info("第一次抓取栏目列表页面");
            }else {
                log.info("已抓取过栏目列表页面，当前缓存大小为：{}", size);
                Object[] keys = pagerCache.asMap().keySet().toArray();
                key = keys.length > 0 ? keys[0].toString() : "";
                if (key.isEmpty()) {
                    log.warn("未找到缓存URL的KEY");
                    return;
                }
                url = pagerCache.getIfPresent(key);
                if (url == null || url.isEmpty()){
                    log.warn("未找到缓存的URL");
                    return;
                }
            }

            if(!parser.isPathAllowed(url)){
                log.warn("Url:{} 依据Robots文件规则，禁止抓取", url);
                return;
            }

            // 创建链接
            Connection conn = Jsoup.connect(url)
                    .timeout(10000) // 设置超时时间（毫秒）
                    .userAgent(USER_AGENT) // 模拟浏览器
                    .ignoreHttpErrors(true); // 忽略 HTTP 错误（如 404）;

            // 获取响应状态码
            Connection.Response response = conn.execute();
            int statusCode = response.statusCode();

            if (statusCode == 200) {
                // 状态码正常，解析文档
                Document document = response.parse();

                // 检查标题
                if (document.title().isEmpty()) {
                    log.warn("警告：页面标题为空");
                    return;
                } else {
                    log.info("抓取到新闻栏目标题--「{}」", document.title());
                }

                // 检查新闻列表分页元素
                Element pager = document.selectFirst("div.listpage.mt30.page_comm");
                if (pager == null || !pager.hasText()) {
                    log.warn("未找到新闻栏目列表分页元素");
                } else {
                    extraPageUrl(pager);
                }

                // 抓取新闻列表外层元素
                Element newsList = document.selectFirst("div.w800.l:not(.tit_pa) ul");
                if (newsList == null || !newsList.hasText()) {
                    log.warn("未找到[新闻列表]元素");
                    return;
                }

                // 获取新闻列表
                newsList.addClass("top");
                Elements items = newsList.select("ul.top > li");
                if (items.isEmpty()) {
                    log.warn("未找到[新闻]元素");
                    return;
                }

                // 遍历新闻列表
                for (org.jsoup.nodes.Element item : items) {
                    // 获取新闻链接
                    Element link = Objects.requireNonNull(item.selectFirst("p.l > a"));
                    // 获取新闻标题
                    Element headline = Objects.requireNonNull(item.selectFirst("p.f22"));
                    // 获取新闻简介
                    Element summary = Objects.requireNonNull(item.selectFirst("p.lh24.mh48.mt10.f14.c6"));

                    log.info("《{}》-- {} 「{}」", headline.text(), link.attr("abs:href"), summary.text());

                    // 抓取新闻内容
                    CompletableFuture<String> contentCompletableFuture = extraNewsContent(link.attr("abs:href"));
                    contentCompletableFuture.thenAccept(content -> log.info("发送【{}】内容：{} 【消息队列】", link, content));
                }


            } else {
                log.warn("请求失败，状态码：{}", statusCode);
            }
        } catch (IOException e) {
            log.error("网络异常：{}", e.getMessage());
        }
    }

    @Async
    public CompletableFuture<String> extraNewsContent(String link) {
        log.info("抓取新闻内容「{}」抓取任务...", link);
        try {
            // 创建链接
            Connection conn = Jsoup.connect(NEWS_URL)
                    .timeout(10000) // 设置超时时间（毫秒）
                    .userAgent(USER_AGENT) // 模拟浏览器
                    .ignoreHttpErrors(true); // 忽略 HTTP 错误（如 404）;

            // 获取响应状态码
            Connection.Response response = conn.execute();

            int statusCode = response.statusCode();

            if (statusCode == 200) {
                // 状态码正常，解析文档
                Document document = response.parse();

                // 检查标题
                if (document.title().isEmpty()) {
                    log.warn("警告：新闻内容页面标题为空");
                    return CompletableFuture.completedFuture("no title");
                } else {
                    log.info("抓取到新闻内容标题--「{}」", document.title());
                }

                // 抓取新闻列表外层元素
                Element newsContent = document.selectFirst("div.w800.l:not(.tit_pa)");

                if (newsContent == null || !newsContent.hasText()) {
                    log.warn("未找到[新闻内容]元素");

                    return CompletableFuture.completedFuture("no Content");
                }

                return CompletableFuture.completedFuture(newsContent.text());

            } else {
                log.warn("新闻内容--请求失败，状态码：{}", statusCode);
            }
        } catch (IOException e) {
            log.error("新闻内容--网络异常：{}", e.getMessage());
        }

        return CompletableFuture.completedFuture("no Result");

    }

    @Async
    public void extraPageUrl(Element pager) {
        log.info("开始执行分页URL抓取任务...");
        Elements pages = pager.select("a[href]");
        for (Element page : pages) {
            String url = page.attr("abs:href");
            if(!parser.isPathAllowed(url))
                continue;
            String key = sha1(url);
            if(pagerCache.getIfPresent(key) == null) {
                log.info("【缓存列表分页URL】 ：「{}」", url);
                pagerCache.put(key, url);
            }
        }
    }

    private String sha1(String input) {
        try {
            // 获取SHA-1消息摘要实例并计算哈希值
            MessageDigest md = MessageDigest.getInstance("SHA-1");
            byte[] hashBytes = md.digest(input.getBytes(StandardCharsets.UTF_8));
            // 将字节数组转换为十六进制字符串
            return HexFormat.of().formatHex(hashBytes); // Java 17+ 更简洁
        } catch (Exception e) {
            throw new RuntimeException("SHA-1计算失败", e);
        }
    }
}
